home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / graphics / raymovi2.arc / FIND.C < prev    next >
C/C++ Source or Header  |  1988-12-21  |  3KB  |  158 lines

  1. #include <math.h>
  2. #include "rtd.h"
  3. #include "extern.h"
  4.  
  5. /* find where a ray leaves a sphere */
  6.  
  7. double  findo (m, s)
  8.     struct mat *m;
  9.     struct sphere  *s;
  10. {
  11.     struct vector   foops;
  12.     double  t;
  13.  
  14.     /* foops is the rotated vector for the center of the sphere
  15.        with respect to the beginning of the ray */
  16.  
  17.     mt_vec (&foops, m, &(s->cent));
  18.  
  19.     /* find out if the center of the sphere is within range.
  20.         (it should be for this...)*/
  21.  
  22.     t = s->rad * s->rad - foops.y * foops.y - foops.z * foops.z;
  23.  
  24.     /*return distance from original entry. we can find the point 
  25.        when we get out*/
  26.  
  27.     if (t > 0)
  28.     t = foops.x + sqrt (t);
  29.     else
  30.     t = 0;
  31.  
  32.     return (t);
  33. }
  34.  
  35.  
  36. /* find where a ray next hits (enters or exits) a sphere */
  37.  
  38. double  findx (m, s)
  39.     struct mat *m;
  40.     struct sphere  *s;
  41. {
  42.     struct vector   foops;
  43.     double  t;
  44.  
  45.     /* foops is the rotated vector for the center of the sphere
  46.        with respect to the beginning of the ray */
  47.     mt_vec (&foops, m, &s->cent);
  48.     t = s->rad*s->rad - foops.y*foops.y - foops.z*foops.z;
  49.     if (t < 0)
  50.     t = HUGE;           /* doesn't touch, return flag */
  51.     else
  52.     {    t = sqrt(t);
  53.     if (foops.x > t + EPSILON)
  54.         t = foops.x - t;   /* return distance to entering */
  55.     else if (foops.x > - t + EPSILON)
  56.         t = -foops.x - t;  /* return minus distance to exiting */
  57.     else
  58.         t = HUGE;
  59.     }
  60.     return (t);
  61. }
  62.  
  63. /* see above. the only difference is that 
  64. the value returned is foops.x - sqrt(t) */
  65.  
  66. double  find (m, s)
  67.     struct mat *m;
  68.     struct sphere  *s;
  69. {
  70.     struct vector   foops;
  71.     double  t;
  72.  
  73.     mt_vec (&foops, m, &(s->cent));
  74.  
  75.     t = s->rad * s->rad - foops.y * foops.y - foops.z * foops.z;
  76.  
  77.     if (t > 0)
  78.     t = foops.x - sqrt (t);
  79.     else
  80.     t = 0;
  81.  
  82.     return (t);
  83. }
  84.  
  85.  
  86. /* returns value telling how much a sphere
  87. is occluding the light source */
  88.  
  89. double  finds (m, s)
  90.     struct mat *m;
  91.     struct sphere  *s;
  92. {
  93.     struct vector   foops;
  94.     double  t;
  95.  
  96.     mt_vec (&foops, m, &(s->cent));
  97.  
  98.     t = s->rad - sqrt (foops.y * foops.y + foops.z * foops.z);
  99.  
  100.     if (t > 0)
  101.     t = t / foops.x;
  102.     else
  103.     t = 0;
  104.  
  105.     return (t);       /* radians between ray and edge of intersecting sphere*/
  106. }
  107.  
  108.  
  109. /* gets amount of diffuse light hitting a point */
  110.  
  111. float   shadow (p, rd, gn, blu)
  112. struct vector  *p;
  113. double *rd, *gn, *blu;
  114. {
  115.     struct mat  trans;
  116.     struct sphere   ss;
  117.     struct vector   d;
  118.     int     c,
  119.             i;
  120.     double  l,
  121.             k,
  122.             x,
  123.             y,
  124.             z,
  125.             finds ();
  126.  
  127.     l = 0.0;
  128.     c = -1;
  129.     sv (&d, &(ls.cent), p);
  130.     vecl (&d);  /*!!*/
  131.     vexzl (&d); /*!!*/
  132.     mt (&(d), &trans);
  133.  
  134.     /* get maximum obscurment */
  135.  
  136.     for (i = 0; i < nob; i++) {
  137.     ss.rad = bl[i].s.rad;
  138.     sv (&(ss.cent), &(bl[i].s.cent), p);
  139.     if ((k = finds (&trans, &ss)) > l) {
  140.         c = i;
  141.         l = k;
  142.     }
  143.     }
  144.  
  145.     if (c == -1)
  146.     k = 255.0;
  147.     else {    
  148.     k = 1.0 - l * d.l / ls.rad;
  149.     if (k < 0.0)    /* l           = angle to move to get ray out of sphere*/
  150.         k = 0.0;    /* d.l/ls.rad = 1/angle light source subtends */
  151.     else
  152.         k *= 255.0;
  153.     }
  154.     *rd = *gn = *blu = k;    /* all colors the same for now */
  155. }
  156.  
  157.  
  158.